import HelperFunctions as HF
import numpy as np
from numpy import array
import csv
import random
from datetime import datetime
from time import strftime

'''
revision of test18
'''

def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def build_value_lists_from_csv(cancerFN):
    sKey = np.array([])
    #read contiguity file
    fn = inputAttriCSV

    #print "Strat building csv lists..."

    ra = csv.DictReader(file(fn), dialect="excel")
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record["ID"])), int(float(record[cancerFN])),int(float(record[popFN])),float(record["Area"])]
        #print temp
        sKey =np.append(sKey, temp)
    sKey.shape=(-1,4)
    return sKey


def build_value_lists(cancerFN):
    """Reads through feature table extracting geometry and field info.
       Returns this information in dictionary structures."""

    pRows = HF.pGP.SearchCursor(inputs.sInputFC)
    # pRows = pGP.SearchCursor(inputs.sOutputFC)
    pRow = pRows.Next()
    sKey = np.array([])
    lsBadRecs = []
    iBadRecCnt = 0
    iRec = 0 


    #print "Strat building attribute lists..."
    
    
    while pRow <> None:
        iRec = iRec + 1
        try:
            dTemp = []
            dTemp.append(pRow.GetValue("FID"))
            dTemp.append(pRow.GetValue(cancerFN))
            dTemp.append(pRow.GetValue(inputs.sField_Pop))
            dTemp.append(pRow.GetValue("Area"))
            sKey=np.append(sKey,dTemp)
        except:
            iBadRecCnt += 1
        pRow = pRows.Next()
    
    #print iBadRecCnt     
    # Report any problems encountered reading feature input data.
    if iBadRecCnt:
        sMessage = HF.msgReadErr % (iBadRecCnt, iRec)
        HF.pGP.AddWarning (sMessage)
        HF.pGP.AddWarning(`lsBadRecs`)


    sKey.shape = (-1,4)
    
    #print sKey    
    return sKey #[[FID, cancer, pop],[FID, cancer, pop, area], ... ]

def build_csv_list(inputCSV):
    spDissovle = np.array([],dtype=int)
    #read contiguity file
    fn = inputCSV

    #print "Strat building csv lists..."

    ra = csv.DictReader(file(fn), dialect="excel")       
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record[ra.fieldnames[0]])), int(float(record[ra.fieldnames[-1]]))]
        #print temp
        spDissovle =np.append(spDissovle, temp)
    spDissovle.shape=(-1,2)
    return spDissovle

def find_same_region(regionID):
    # return the original item id list within a region 
    iLen = csv_attri.shape
    i = 0
    temp = []
    while i < iLen[0]:
        if csv_attri[i,1] == regionID:
            temp = np.append(temp, csv_attri[i,0])
        i = i + 1
    return temp

def cal_region_rate(regionList):
    # calculate rate = cancer/pop for each region
    # return a list
    iLen = regionList.shape
    reg_rate = np.array([])

    i = 0
    while i < iLen[0]:
        temp = find_same_region(regionList[i])
        temp_cancer = 0
        temp_pop = 0
        for item in temp:
            temp_cancer = temp_cancer + attri[item, 1]
            temp_pop = temp_pop + attri[item, 2]
        temp_rate = temp_cancer/temp_pop
        reg_rate = np.append(reg_rate, [regionList[i], temp_rate])
        i = i + 1
    reg_rate.shape = (-1, 2)
    return reg_rate
    
def find_rep_region(unitList, listID):
    temp = np.array([])
    totalPop = 0
    totalCancer = 0
    totalArea = 0
    i = 0
    for item in unitList:
        temp = np.append(temp, int(csv_attri[item,1]))
        totalPop = totalPop + attri[item, 2]
        totalCancer = totalCancer + attri[item, 1]
        totalArea = totalArea + attri[item, 3]
        i = i + 1
    #temp.shape = (-1, 2)
    dis_region = np.unique(temp) # distinct region ID in the unitList
    reg_pop = np.array([])
    reg_cancer = np.array([])
    #reg_rate = np.array([])
    #reg_area = np.array([])
    temp_type_two_error = np.array([])
    
    for region in dis_region:
        temp_pop = 0    # within the risk area
        temp_cancer = 0 # within the risk area
        temp_area = 0   # within the risk area
        temp_whole_pop = 0 # within the region
        temp_whole_cancer = 0   # within the region
        temp_whole_area = 0 # within the region
        for unit in unitList:
            if int(csv_attri[unit, 1] ) == int(region):
                temp_pop = temp_pop + attri[unit, 2]
                temp_cancer = temp_cancer +  attri[unit, 1]
                temp_area = temp_area + attri[unit, 3]
            temp_whole_pop = temp_whole_pop + attri[unit, 2]
            temp_whole_cancer = temp_whole_cancer +  attri[unit, 1]
            temp_whole_area = temp_whole_area + attri[unit, 3]
        reg_pop = np.append(reg_pop, [int(temp_pop), int(temp_whole_pop)])
        reg_cancer = np.append(reg_cancer, [int(temp_cancer), int(temp_whole_cancer)])
        #reg_rate = np.append(reg_rate, [temp_cancer/temp_pop, temp_whole_cancer/temp_whole_pop])
        #reg_area = np.append(reg_area, [temp_area, temp_whole_area])
    #print "reg_rate = ", reg_rate
    reg_pop.shape = (-1,2)  #[[pop within the risk are, pop within the region],[]]
    reg_cancer.shape = (-1,2)   #[[cancer within the risk are, cancer within the region],[]]
    #reg_rate.shape = (-1,2)
    #reg_area.shape = (-1,2)
    temp_rep_id = np.array([])

    iLen = dis_region.shape    

    if returnID == 0:
        i = 0
        while i < iLen[0]:
            # if the pop within the risk area is more than half of the whole pop within the region
            if reg_pop[i,0]/reg_pop[i,1] > 0.5:  
                temp_rep_id = np.append(temp_rep_id, i)
            # if the pop within the risk area is more than half of the whole pop within the risk area
            if reg_pop[i,0]/totalPop > 0.5: 
                temp_rep_id = np.append(temp_rep_id, i)
            i = i + 1
    elif returnID == 1:
        i = 0
        while i < iLen[0]:
            # if the cancer within the risk area is more than half of the whole cancer within the region
            if reg_cancer[i,0]/reg_cancer[i,1] > 0.5:  
                temp_rep_id = np.append(temp_rep_id, i)
            # if the cancer within the risk area is more than half of the whole cancer within the risk area
            if reg_cancer[i,0]/totalCancer > 0.5: 
                temp_rep_id = np.append(temp_rep_id, i)
            i = i + 1
    temp_rep_id = np.unique(temp_rep_id)

    if temp_rep_id.shape[0] == 0:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, returnID])

    temp_reg_id = []
    for item in temp_rep_id:
        temp_reg_id.append(int(dis_region[item]))
        
    return temp_reg_id, temp_type_two_error
    '''
    if returnID == 0:     
        # return max_pop
        # find the maximum pop and its id 
        i = 0
        temp_max_pop = 0
        temp_max_pop_id = 0
        for pop in reg_pop[:,0]:
            if pop > temp_max_pop:
                temp_max_pop = pop
                temp_max_pop_id = i
            i = i + 1
        temp_max_id = temp_max_pop_id
        if  reg_pop[temp_max_id, 0]/totalPop < 0.5:
            for pop in reg_pop[:,1]:
                if pop
            temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 0])
    elif returnID == 1:
        # return max_cancer
        # find the maximum cancer and its id    
        i = 0
        temp_max_cancer = 0
        temp_max_cancer_id = 0
        for cancer in reg_cancer:
            if cancer > temp_max_cancer:
                temp_max_cancer = cancer
                temp_max_cancer_id = i
            i = i + 1
        temp_max_id = temp_max_cancer_id
        if  reg_cancer[temp_max_id]/totalCancer < 0.5:
            temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 1])
    elif returnID == 2: 
        # return max or min cancer
        if listID in [1,3,4,7]: # high risk area, return max cancer id
            # find the maximum rate and its id
            i = 0
            temp_max_rate = 0
            temp_max_rate_id = 0
            for rate in reg_rate:
                if rate > temp_max_rate:
                    temp_max_rate = rate
                    temp_max_rate_id = i
            i = i + 1
            temp_max_id = temp_max_rate_id 
        elif listID in [2,5,6]: # low risk area, return min cancer id
            # find the minimum rate and its id
            i = 0
            temp_min_rate = 1
            temp_min_rate_id = 0
            for rate in reg_rate:
                if rate < temp_min_rate:
                    temp_min_rate = rate
                    temp_min_rate_id = i
            i = i + 1
            temp_max_id = temp_min_rate_id 
    elif returnID == 3:
        # return max_area
        # find the maximum area and its id    
        i = 0
        temp_max_area = 0
        temp_max_area_id = 0
        for area in reg_area:
            if area > temp_max_area:
                temp_max_area = area
                temp_max_area_id = i
            i = i + 1
        temp_max_id = temp_max_area_id
        if  reg_area[temp_max_id]/totalArea < 0.5:
            temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 3])
            #print sField_Ob, "'s region ", listID, "does not have half area of its representive risk area"

         
    if  reg_pop[temp_max_id]/totalPop < 0.5:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 0])
        #print sField_Ob, "'s region ", listID, "does not have half pop of its representive risk area"
    if  reg_cancer[temp_max_id]/totalCancer < 0.5:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 1])
        #print sField_Ob, "'s region ", listID, "does not have half cancer of its representive risk area"
    
    return int(dis_region[temp_max_id]), totalPop, totalCancer, reg_pop[temp_max_id], reg_cancer[temp_max_id], temp_type_two_error
    '''
def find_max_id(list):
    # return the id of the maximum value
    i = 0
    temp_max = 0
    temp_max_id = 0
    
    for item in list:
        if item > temp_max:
            temp_max = item
            temp_max_id = i
        i = i + 1
    return temp_max_id           

def find_min_id(list):
    # return the id of the maximum value
    i = 0
    temp_min = 1000000
    temp_min_id = 0
    
    for item in list:
        if item < temp_min:
            temp_min = item
            temp_min_id = i
        i = i + 1
    return temp_min_id

def calMeasure():
    H1 = [8,16,844,915,919,921,923,924]
    L2 = [5,103,106,513,517,518,520,531,534,535,536,541]
    H3 = [63,265,267,268,333,336,337,339,340,342,343,348]
    H4 = [13,174,178,198,886,887,888,889,890]
    L5 = [146,171,182,810,811,814,815,864,867]
    L6 = [20,133,692,694,695,696,698,702,705]
    H7 = [69,70,87,88,369,370,372,442,443]

    high_risk_region = np.array([])
    low_risk_regioin = np.array([])
    #tempPopCancer = np.array([])
    tempC_type_two_error = np.array([])
    
    tempListID = 1 
    tempID, temp_type_two_error = find_rep_region(H1, tempListID)
    high_risk_region = np.append(high_risk_region, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 2
    tempID, temp_type_two_error = find_rep_region(L2, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 3
    tempID, temp_type_two_error = find_rep_region(H3, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 4
    tempID, temp_type_two_error = find_rep_region(H4, tempListID)   
    high_risk_region = np.append(high_risk_region, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 5
    tempID, temp_type_two_error = find_rep_region(L5, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 6    
    tempID, temp_type_two_error = find_rep_region(L6, tempListID)    
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 7    
    tempID, temp_type_two_error = find_rep_region(H7, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)
    #tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)

    #high_rep_count = 4
    #low_rep_count = 3    
    
    temp_high_rate = np.array([])
    for region in high_risk_region:
        for rate in reg_rate:
            if int(rate[0]) == int(region):
                temp_high_rate = np.append(temp_high_rate, [region, rate[1]])
                break
    temp_high_rate.shape = (-1,2)

    temp_low_rate = np.array([])    
    for region in low_risk_regioin:
        for rate in reg_rate:
            #print int(rate[0]), int(region)
            if int(rate[0]) == int(region):
                temp_low_rate = np.append(temp_low_rate, [region, rate[1]])
                break        
    temp_low_rate.shape = (-1,2)
    
    high_region_num = 0
    low_region_num = 0
    
    if temp_high_rate.shape[0] == 0:
        high_region_num = 999
        if temp_low_rate.shape[0] == 0:
            low_region_num = 999
        else:
            max_low_rate = temp_low_rate[find_max_id(temp_low_rate[:,1]), 1]
            for rate in reg_rate[:,1]:
                if rate <= max_low_rate:
                    low_region_num = low_region_num + 1
    else:
        if temp_low_rate.shape[0] == 0:
            low_region_num = 999
            min_high_rate = temp_high_rate[find_min_id(temp_high_rate[:,1]), 1]
            for rate in reg_rate[:,1]:
                if rate >= min_high_rate:
                    high_region_num = high_region_num + 1
        else:
            min_high_rate = temp_high_rate[find_min_id(temp_high_rate[:,1]), 1]
            max_low_rate = temp_low_rate[find_max_id(temp_low_rate[:,1]), 1]
            for rate in reg_rate[:,1]:
                if rate >= min_high_rate:
                    high_region_num = high_region_num + 1
                if rate <= max_low_rate:
                    low_region_num = low_region_num + 1
            

    #min_high_rate_region = int(temp_high_rate[find_min_id(temp_high_rate[:,1]), 0])
    #max_low_rate_region = int(temp_low_rate[find_max_id(temp_low_rate[:,1]), 0])

    #min_high_rate = temp_high_rate[find_min_id(temp_high_rate[:,1]), 1]
    #max_low_rate = temp_low_rate[find_max_id(temp_low_rate[:,1]), 1]   

    #high_region_num = 0
    #low_region_num = 0
    #for rate in reg_rate[:,1]:
        #if rate >= min_high_rate:
            #high_region_num = high_region_num + 1
        #if rate <= max_low_rate:
            #low_region_num = low_region_num + 1
    #print "high_region_num =", high_region_num
    #print "low_region_num = ", low_region_num
    '''
    if high_risk_region.shape[0] > 4:
        high_rep_count = high_risk_region.shape[0]
    if low_risk_regioin.shape[0] > 3:
        low_rep_count = low_risk_regioin.shape[0]
    '''
    return high_risk_region.shape[0], high_region_num, low_risk_regioin.shape[0], low_region_num, tempC_type_two_error


#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    #inputs = get_inputs()
    print "begin at " + getCurTime()
    inputAttriCSV = "C:/TP1000_1m.csv"
    popFN = "pop"
    soMethod = "OO"
    filePath = "C:/_DATA/CancerData/test/Jan15/Thousand/67regions/OO_WARD/"

	# returnID used in function find_rep_region

    returnID = 0  # 0: return max_pop, 1: return max_cancer, 2: return max_rate or min_rate, 3: return max_area
    
    while returnID < 2:
        type_two_error = np.array([])
        high_low_measure = np.array([])
        repeat = 1
        #PopCancer = np.array([])
        
        while repeat < 1001:
            sInputCSV = filePath + "OO_WARDcancer"+ str(repeat) +".csv"
            sField_Ob = "cancer" + str(repeat)
            attri = build_value_lists_from_csv(sField_Ob) #[[FID, cancer, pop, area],[FID, cancer, pop, area], ... ]
            csv_attri = build_csv_list(sInputCSV)
            dis_reg = np.unique(csv_attri[:,1])
            reg_rate = cal_region_rate(dis_reg)
            temp_high_count, temp_high, temp_low_count, temp_low, temp_type_two_error = calMeasure()
            #PopCancer = np.append(PopCancer, tempPopCancer)
            high_low_measure = np.append(high_low_measure, [temp_high_count, temp_high, temp_low_count, temp_low])
            type_two_error = np.append(type_two_error, temp_type_two_error)
            repeat = repeat + 1

        high_low_measure.shape = (-1,4)

        if returnID == 0:
            txtName_HLM = filePath + soMethod + "_Max_Pop.txt"
            txtName_PC = filePath + soMethod + "_Max_Pop_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Pop_type_two_error.txt"
        elif returnID == 1:
            txtName_HLM = filePath + soMethod + "_Max_Cancer.txt"
            txtName_PC = filePath + soMethod + "_Max_Cancer_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Cancer_type_two_error.txt"
        elif returnID == 2:
            txtName_HLM = filePath + soMethod + "_Max_Rate.txt"
            txtName_PC = filePath + soMethod + "_Max_Rate_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Rate_type_two_error.txt"
        elif returnID == 3:
            txtName_HLM = filePath + soMethod + "_Max_Area.txt"
            txtName_PC = filePath + soMethod + "_Max_Area_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Area_type_two_error.txt"

        #print high_low_measure
        np.savetxt(txtName_HLM, high_low_measure, delimiter=',')
        #PopCancer.shape = (-1, 28)
        #print PopCancer
        #np.savetxt(txtName_PC, PopCancer, delimiter=',')
        type_two_error.shape = (-1, 3)
        print "type_two_error = ", type_two_error.shape[0]
        np.savetxt(txtNameTTE, type_two_error, delimiter=',')
        
        del type_two_error, high_low_measure, repeat
        returnID = returnID + 1

    print "end at " + getCurTime()
    print "========================================================================"  
    print "========================================================================"
    

    #print "temp_high_rate =", min_high_rate
    #print "temp_low_rate=", max_low_rate
    #print temp_high_rate, temp_low_rate
    #print high_risk_region, low_risk_regioin

    #output_results()  

           
